package com.kapcb.secure.configuration.configuration;

import com.kapcb.common.constant.StringPool;
import com.kapcb.secure.configuration.constant.ConfigurationConstant;
import com.kapcb.secure.configuration.core.ConfigurationSecurer;
import com.kapcb.secure.configuration.core.EncryptorManager;
import com.kapcb.secure.configuration.filter.CryptoFilter;
import com.kapcb.secure.configuration.interceptor.MybatisDecryptInterceptor;
import com.kapcb.secure.configuration.interceptor.MybatisEncryptInterceptor;
import com.kapcb.secure.configuration.properties.ApiDecryptProperties;
import com.kapcb.secure.configuration.properties.EncryptorProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;
import javax.servlet.DispatcherType;

/**
 * <a>Title: ConfigurationSecurerAutoConfiguration </a>
 * <a>Author: cb <a>
 * <a>Description: 配置文件保护者自动装配 <a>
 *
 * @author cb
 * @version 1.0
 * @date 2024/4/20 11:03 PM
 * @since 1.0
 */
@Slf4j
@AutoConfiguration
@EnableConfigurationProperties(value = {ApiDecryptProperties.class, EncryptorProperties.class})
public class ConfigurationSecurerAutoConfiguration {

    private final EncryptorProperties encryptorProperties;

    public ConfigurationSecurerAutoConfiguration(EncryptorProperties encryptorProperties) {
        this.encryptorProperties = encryptorProperties;
    }

    /**
     * 自动装配配置文件保护者
     *
     * @return ConfigurationSecurer 配置文件保护者
     */
    @Bean
    @ConditionalOnMissingBean(ConfigurationSecurer.class)
    @ConditionalOnProperty(prefix = ConfigurationConstant.ENABLE_CONFIGURATION_SECURE, havingValue = StringPool.TRUE)
    public ConfigurationSecurer configurationSecurer() {
        if (log.isDebugEnabled()) {
            log.debug("begin load ConfigurationSecurer into IOC ...");
        }
        return new ConfigurationSecurer();
    }

    /**
     * 接口自动加密过滤器自动注册
     *
     * @param apiDecryptProperties ApiDecryptProperties
     * @return 过滤器
     */
    @Bean
    @ConditionalOnMissingBean(CryptoFilter.class)
    @ConditionalOnProperty(value = ConfigurationConstant.ENABLE_API_SECURE, havingValue = StringPool.TRUE)
    public FilterRegistrationBean<CryptoFilter> cryptoFilter(ApiDecryptProperties apiDecryptProperties) {
        if (log.isDebugEnabled()) {
            log.debug("begin load API Crypto Filter into IOC ...");
        }
        FilterRegistrationBean<CryptoFilter> registration = new FilterRegistrationBean<>();
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        registration.setFilter(new CryptoFilter(apiDecryptProperties));
        registration.addUrlPatterns("/*");
        registration.setName("cryptoFilter");
        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
        return registration;
    }

    @Bean
    public EncryptorManager encryptorManager() {
        if (log.isDebugEnabled()) {
            log.debug("begin load MybatisEncryptInterceptor into IOC ...");
        }
        return new EncryptorManager();
    }

    @Bean
    @ConditionalOnProperty(value = ConfigurationConstant.ENABLE_MYBATIS_SECURE, havingValue = StringPool.TRUE)
    public MybatisEncryptInterceptor mybatisEncryptInterceptor() {
        if (log.isDebugEnabled()) {
            log.debug("begin load MybatisEncryptInterceptor into IOC ...");
        }
        return new MybatisEncryptInterceptor(encryptorManager(), encryptorProperties);
    }

    @Bean
    @ConditionalOnProperty(value = ConfigurationConstant.ENABLE_MYBATIS_SECURE, havingValue = StringPool.TRUE)
    public MybatisDecryptInterceptor mybatisDecryptInterceptor() {
        if (log.isDebugEnabled()) {
            log.debug("begin load MybatisDecryptInterceptor into IOC ...");
        }
        return new MybatisDecryptInterceptor(encryptorManager(), encryptorProperties);
    }

}
